<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>ES6变量的解构赋值</title>
	</head>
	<body>
		<script type="text/javascript">
			// 以前
			let a = 1,
				b = 2,
				c = 3;
			// ES6 允许写成下面这样
			let [a, b, c] = [1, 2, 3];

			// 数组的解构赋值
			let [foo, [[bar], baz]] = [1, [[2], 3]]; // foo:1, bar:2, baz:3
			let [, , third] = ["foo", "bar", "baz"]; // third:"baz"
			let [x, , y] = [1, 2, 3]; // x:1, y:3
			let [head, ...tail] = [1, 2, 3, 4]; // head:1, tail:[2, 3, 4]
			let [x, y, ...z] = ['a']; // x:"a", y:undefined, z:[]
			let [a, [b], d] = [1, [2, 3], 4]; // a:1, b:2, d:4

			// Set 结构，也可以使用数组的解构赋值
			// 事实上，只要某种数据结构具有 Iterator 接口，都可以采用数组形式的解构赋值
			let [x, y, z] = new Set(['a', 'b', 'c']); // x:"a", y:"b", z:"c"

			// 对象的解构赋值
			let {a,c} = {a: 'aaa',b: 'bbb'}; // a="aaa", c=undefined
			// 对象的解构赋值，可以很方便地将现有对象的方法，赋值到某个变量
			let {log,sin,cos} = Math;
			const {log} = console; // log('hello') - 控制台打印hello

			// 对象的解构赋值的内部机制，是先找到同名属性，然后再赋给对应的变量
			// 所以真正被赋值的是后者，而不是前者
			let {foo: baz} = {foo: 'aaa',bar: 'bbb'}; // baz="aaa", foo - error: foo is not defined
			
			// 注意！！！
			// 错误，因为 JavaScript 引擎会将{x}理解成一个代码块，从而发生语法错误
			let x;
			{x} = {x: 1};
			//正确
			let x;
			({x} = {x: 1});
			
			// 字符串的解构赋值
			const [a, b, c, d, e] = 'hello'; // a="h", b="e", c="l", d="l", e="o"
			let {length : len} = 'hello'; // len=5
			
			// 函数参数的解构赋值
			function add([x, y]){
			  return x + y;
			}
			add([1, 2]); // 3
			
			
			
			// 解构赋值允许指定默认值
			let [foo = true] = []; // foo=true
			let [x, y = 'b'] = ['a']; // x='a', y='b'
			let [x = 1] = [undefined]; // x=1
			let [x = 1] = [null]; // x=null
			let {x = 3} = {}; // x=3
			let {x, y = 5} = {x: 1}; //x=1, y=5
			let {x: y = 3} = {x: 5}; //y=5
			// 默认值可以引用解构赋值的其他变量，但该变量必须已经声明
			let [x = 1, y = x] = [1, 2]; // x=1, y=2
			
			
			
			// 用途
			// 1、交换变量的值
			let x = 1;
			let y = 2;
			[x, y] = [y, x];
			// 2、从函数返回多个值
			function example() {
			  return {foo: 1, bar: 2};
			}
			let {foo, bar} = example();
			// 3、遍历 Map 结构
			const map = new Map();
			map.set('first', 'hello');
			map.set('second', 'world');
			for (let [key, value] of map) {
			  console.log(key + " is " + value);
			}
			// 4、提取 JSON 数据
			let jsonData = {
			  id: 42,
			  status: "OK",
			  data: [867, 5309]
			};
			let { id, status, data: number } = jsonData;
		</script>
	</body>
</html>
